﻿#include "FITKAbaqusAdaptorSection.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "InpReadInformationMapper.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractSection.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionBeam.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionShellHomogeneous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionSolidHomogeneous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfile.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileI.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileL.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileBox.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfilePipe.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileRectangular.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileCircular.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKSectionAssign.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionAssignShellHomogeneous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionAssignSolidHomogenous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionAssignBeam.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialOrientation.h"
#include "FITK_Kernel/FITKAppFramework/FITKMessage.h"
#include "FITK_Interface/FITKInterfaceModel/FITKModelSet.h"
#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Interface/FITKInterfaceModel/FITKCoordinateSystem.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBeamOrientation.h"
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"
#include <QTextStream>
#include <QList>
#include <QDebug>

namespace IO
{
    QString FITKAbaqusAdaptorSection::getAdaptorClass()
    {
        return "IO::FITKAbaqusAdaptorSection";
    }

    bool FITKAbaqusAdaptorSection::adaptR()
    {
        bool readOK = false;
        Interface::FITKAbaAbastractSection* section = dynamic_cast<Interface::FITKAbaAbastractSection*>(_dataObj);
        if (section == nullptr || _assign == nullptr || _modelData == nullptr || !_reader)
            return readOK;
        //获取类型
        Interface::FITKAbaAbastractSection::FITKAbaSectionType type = section->getSectionType();
        if (type == Interface::FITKAbaAbastractSection::FITKAbaSectionType::Beam)
        {
            readOK = this->beamSectionR();
        }
        else if (type == Interface::FITKAbaAbastractSection::FITKAbaSectionType::ShellHomogeneous)
        {
            readOK = this->shellHomogeneousSectionR();
        }
        else if (type == Interface::FITKAbaAbastractSection::FITKAbaSectionType::SolidHomogeneous)
        {
            readOK = this->solidHomogeneousSectionR();
        }
        return readOK;
    }

    bool FITKAbaqusAdaptorSection::adaptW()
    {
        bool writerOK = false;
        Interface::FITKAbaAbastractSection* section = dynamic_cast<Interface::FITKAbaAbastractSection*>(_dataObj);
        if (section == nullptr || _assign == nullptr)
            return writerOK;

        QString sectionName = section->getDataObjectName();
        QTextStream* stream = _writer->getStream();
        *stream << "** Section: " << sectionName << endl;
        //获取类型
        Interface::FITKAbaAbastractSection::FITKAbaSectionType type = section->getSectionType();

        if (type == Interface::FITKAbaAbastractSection::FITKAbaSectionType::Beam)
        {
            writerOK = this->beamSectionW();
        }
        else if (type == Interface::FITKAbaAbastractSection::FITKAbaSectionType::ShellHomogeneous)
        {
            writerOK = this->shellHomogeneousSectionW();
        }
        else if (type == Interface::FITKAbaAbastractSection::FITKAbaSectionType::SolidHomogeneous)
        {
            writerOK = this->solidHomogeneousSectionW();
        }
        return writerOK;
    }

    void FITKAbaqusAdaptorSection::setSectionAssignAndProfile(Interface::FITKSectionAssign* assign, Interface::FITKAbaProfile* profile)
    {
        _assign = assign;
        _profile = profile;
    }

    void FITKAbaqusAdaptorSection::setModel(Interface::FITKAbstractModel* modelData)
    {
        _modelData = modelData;
    }

    bool FITKAbaqusAdaptorSection::beamSectionR()
    {
        //获取数据存储器
        Interface::FITKAbaSectionBeam* section = dynamic_cast<Interface::FITKAbaSectionBeam*>(_dataObj);
        Interface::FITKAbaSectionAssignBeam* assign = dynamic_cast<Interface::FITKAbaSectionAssignBeam*>(_assign);
        if (!section || !_reader || !assign || !_profile || !_modelData)return false;
        Interface::FITKAbaBeamOrientationManager* beamOrientationManager = nullptr;
        if (_modelData->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AMTMIX)
        {
            //part
            AbaqusData::FITKAbaqusPart* partData = dynamic_cast<AbaqusData::FITKAbaqusPart*>(_modelData);
            if (!partData)return false;
            beamOrientationManager = partData->getBeamOrientationManager();
        }
        if (!beamOrientationManager)return false;
        //回退一行，处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //处理数据
        InpKeyLineSpliter spl(line, _reader);
        //获取材料
        QString materialName = spl["material"];
        if (materialName.isEmpty())
            return false;
        setSectionMaterial(materialName);
        if (spl["temperature"].trimmed().toUpper() == "GRADIENTS")
            section->setTemperatureVariation(Interface::FITKAbaAbastractSection::TemperatureVariation::LinearByGradients);
        else if (spl["temperature"].trimmed().toUpper() == "VALUES")
            section->setTemperatureVariation(Interface::FITKAbaAbastractSection::TemperatureVariation::InterpolatedFromTemperaturePoints);
        //获取elset
        int modelID = this->getSetIDByName(spl["elset"], Interface::FITKModelEnum::FITKModelSetType::FMSElem);
        if (modelID == -1)return false;
        //读取材料方向
        if (spl.hasKey("orientation"))
            if (this->materialOrientationR(line, modelID))
                return false;
        //设置名称
        QString name = QString("%1-").arg(section->getDataObjectName()) + spl["elset"];
        section->setDataObjectName(name);
        assign->assign(modelID, section->getDataObjectID());
        Interface::FITKAbaProfile::FITKAbaProfileShape type = _profile->getShape();
        bool ok = false;
        if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::I)
            ok = this->beamSectionProfileIR();
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::L)
            ok = this->beamSectionProfileLR();
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::Box)
            ok = this->beamSectionProfileBoxR();
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::Pipe)
        {
            Interface::FITKAbaProfilePipe* profile = dynamic_cast<Interface::FITKAbaProfilePipe*>(_profile);
            if (!profile)return false;
            QString beamSectionType = spl["section"].trimmed().toLower();
            if (beamSectionType == "pipe")
                profile->setFormulation(Interface::FITKAbaProfilePipe::PipeFormulation::ThinWalled);
            else if (beamSectionType == "thick pipe")
                profile->setFormulation(Interface::FITKAbaProfilePipe::PipeFormulation::ThickWalled);
            ok = this->beamSectionProfilePipeR();
        }
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::Circular)
            ok = this->beamSectionProfileCircularR();
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::Rectangular)
            ok = this->beamSectionProfileRectangularR();
        if (!ok)
            return false;
        section->setProfileId(_profile->getDataObjectID());
        //读取方向
        QStringList str = _reader->readLine().trimmed().split(',');
        if (str.size() < 3)return false;
        std::array<double, 3> dire{ 0.0,0.0,0.0 };
        dire[0] = str.at(0).trimmed().toDouble(&ok);
        if (!ok)return false;
        dire[1] = str.at(1).trimmed().toDouble(&ok);
        if (!ok)return false;
        dire[2] = str.at(2).trimmed().toDouble(&ok);
        if (!ok)return false;
        Interface::FITKAbaBeamOrientation* beamDire = new Interface::FITKAbaBeamOrientation;
        beamDire->setModelSetID(modelID);
        beamDire->setN1Direction(dire);
        beamOrientationManager->appendDataObj(beamDire);
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileIR()
    {
        //获取剖面的存储器
        Interface::FITKAbaProfileI* profile = dynamic_cast<Interface::FITKAbaProfileI*>(_profile);
        if (!profile)return false;
        QString line = _reader->readLine();
        //处理数据
        QStringList str = line.split(',');
        if (str.size() < 7)return false;
        //获取l,h,b1,b2,t1,t2,t3的数据
        bool ok = false;
        double l = str.at(0).trimmed().toDouble(&ok);
        if (!ok) return false;
        double h = str.at(1).trimmed().toDouble(&ok);
        if (!ok) return false;
        double b1 = str.at(2).trimmed().toDouble(&ok);
        if (!ok) return false;
        double b2 = str.at(3).trimmed().toDouble(&ok);
        if (!ok) return false;
        double t1 = str.at(4).trimmed().toDouble(&ok);
        if (!ok) return false;
        double t2 = str.at(5).trimmed().toDouble(&ok);
        if (!ok) return false;
        double t3 = str.at(6).trimmed().toDouble(&ok);
        if (!ok) return false;
        //设置数据
        profile->setI(l);
        profile->seth(h);
        profile->setb1(b1);
        profile->setb2(b2);
        profile->sett1(t1);
        profile->sett2(t2);
        profile->sett3(t3);
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileLR()
    {
        //获取剖面的存储器
        Interface::FITKAbaProfileL* profile = dynamic_cast<Interface::FITKAbaProfileL*>(_profile);
        if (!profile)return false;
        QString line = _reader->readLine();
        //处理数据
        QStringList str = line.split(',');
        if (str.size() < 4)return false;
        //获取a,b,t1,t2的数据
        bool ok = false;
        double a = str.at(0).trimmed().toDouble(&ok);
        if (!ok) return false;
        double b = str.at(1).trimmed().toDouble(&ok);
        if (!ok) return false;
        double t1 = str.at(2).trimmed().toDouble(&ok);
        if (!ok) return false;
        double t2 = str.at(3).trimmed().toDouble(&ok);
        if (!ok) return false;
        //设置数据
        profile->setA(a);
        profile->setB(b);
        profile->setT1(t1);
        profile->setT2(t2);
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileBoxR()
    {
        //获取剖面的存储器
        Interface::FITKAbaProfileBox* profile = dynamic_cast<Interface::FITKAbaProfileBox*>(_profile);
        if (!profile)return false;
        QString line = _reader->readLine();
        //处理数据
        QStringList str = line.split(',');
        if (str.size() < 6)return false;
        //获取width, height, t1, t2, t3, t4的数据
        bool ok = false;
        double width = str.at(0).trimmed().toDouble(&ok);
        if (!ok) return false;
        double height = str.at(1).trimmed().toDouble(&ok);
        if (!ok) return false;
        double t1 = str.at(2).trimmed().toDouble(&ok);
        if (!ok) return false;
        double t2 = str.at(3).trimmed().toDouble(&ok);
        if (!ok) return false;
        double t3 = str.at(4).trimmed().toDouble(&ok);
        if (!ok) return false;
        double t4 = str.at(5).trimmed().toDouble(&ok);
        if (!ok) return false;
        //设置thickness类型
        profile->setThicknessType(Interface::FITKAbaProfileBox::BoxThickness::Individual);
        //设置数据
        profile->setWidth(width);
        profile->setHeight(height);
        profile->setT1(t1);
        profile->setT2(t2);
        profile->setT3(t3);
        profile->setT4(t4);
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfilePipeR()
    {
        //获取剖面的存储器
        Interface::FITKAbaProfilePipe* profile = dynamic_cast<Interface::FITKAbaProfilePipe*>(_profile);
        if (!profile)return false;
        QString line = _reader->readLine();
        //处理数据
        QStringList str = line.split(',');
        if (str.size() < 2)return false;
        //获取radius,thickness的数据
        bool ok = false;
        double radius = str.at(0).trimmed().toDouble(&ok);
        if (!ok) return false;
        double thickness = str.at(1).trimmed().toDouble(&ok);
        if (!ok) return false;
        //设置数据
        profile->setRadius(radius);
        profile->setThickness(thickness);
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileCircularR()
    {
        //获取剖面的存储器
        Interface::FITKAbaProfileCircular* profile = dynamic_cast<Interface::FITKAbaProfileCircular*>(_profile);
        if (!profile)return false;
        QString line = _reader->readLine();
        //处理数据
        QStringList str = line.split(',');
        if (str.size() < 1)return false;
        //获取radius,thickness的数据
        bool ok = false;
        double r = str.at(0).trimmed().toDouble(&ok);
        if (!ok) return false;
        //设置数据
        profile->setR(r);
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileRectangularR()
    {
        //获取剖面的存储器
        Interface::FITKAbaProfileRectangular* profile = dynamic_cast<Interface::FITKAbaProfileRectangular*>(_profile);
        if (!profile)return false;
        QString line = _reader->readLine();
        //处理数据
        QStringList str = line.split(',');
        if (str.size() < 2)return false;
        //获取radius,thickness的数据
        bool ok = false;
        double a = str.at(0).trimmed().toDouble(&ok);
        if (!ok) return false;
        double b = str.at(1).trimmed().toDouble(&ok);
        if (!ok) return false;
        //设置数据
        profile->setA(a);
        profile->setB(b);
        return true;
    }

    bool FITKAbaqusAdaptorSection::shellHomogeneousSectionR()
    {
        bool ok = false;
        //获取数据存储器
        Interface::FITKAbaSectionShellHomogeneous* section = dynamic_cast<Interface::FITKAbaSectionShellHomogeneous*>(_dataObj);
        Interface::FITKAbaSectionAssignShellHomogeneous* assign = dynamic_cast<Interface::FITKAbaSectionAssignShellHomogeneous*>(_assign);
        if (!section || !_reader || !_assign)
            return false;
        //回退一行，处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //处理数据
        InpKeyLineSpliter spl(line, _reader);
        QString materialName = spl["material"];//获取材料
        if (materialName.isEmpty())
            return false;
        setSectionMaterial(materialName);
        int modelID = this->getSetIDByName(spl["elset"], Interface::FITKModelEnum::FITKModelSetType::FMSElem);
        if (modelID == -1)return false;
        QString name = QString("%1-").arg(section->getDataObjectName()) + spl["elset"];
        section->setDataObjectName(name);//设置名称
        //读取材料方向
        if (spl.hasKey("orientation"))
            if (!this->materialOrientationR(line, modelID))
                return false;
        QString offset = spl["offset"].toLower();//获取偏移量
        if (offset == "")
        {
            assign->setShellOffset(Interface::FITKShellAssignEnum::ShellOffset::MiddleSurface);
        }
        else if (offset == "spos")
        {
            assign->setShellOffset(Interface::FITKShellAssignEnum::ShellOffset::TopSurface);
        }
        else if (offset == "sneg")
        {
            assign->setShellOffset(Interface::FITKShellAssignEnum::ShellOffset::BottomSurface);
        }
        else if (offset == "!")
        {//几何还未生成过
            assign->setShellOffset(Interface::FITKShellAssignEnum::ShellOffset::SFFromGeometry);
        }
        else
        {
            assign->setShellOffset(Interface::FITKShellAssignEnum::ShellOffset::SpecifyValue);
            double value = offset.toDouble(&ok);
            if (ok)
                assign->setShellOffsetValue(value);
        }
        //读取下一行数据
        line = _reader->readLine();
        //获取厚度与积分点
        QStringList lis = line.split(',');
        if (lis.size() < 2)
            return false;
        //设置厚度
        double thickness = lis.at(0).toDouble(&ok);
        if (ok == false)
            return false;
        section->setThickness(thickness);
        //设置积分点
        int intergrationPoints = lis.at(1).toInt(&ok);
        if (ok == false)
            return false;
        section->setThicknessIntergrationPoints(intergrationPoints);
        assign->assign(modelID, section->getDataObjectID());
        //读取下一行数据
        line = _reader->readLine();
        return true;
    }

    bool FITKAbaqusAdaptorSection::solidHomogeneousSectionR()
    {
        //获取数据存储器
        Interface::FITKAbaSectionSolidHomogeneous* section = dynamic_cast<Interface::FITKAbaSectionSolidHomogeneous*>(_dataObj);
        Interface::FITKAbaSectionAssignSolidHomogenous* assign = dynamic_cast<Interface::FITKAbaSectionAssignSolidHomogenous*>(_assign);
        if (!section || !_reader || !_assign)
            return false;
        //回退一行，处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //处理数据
        InpKeyLineSpliter spl(line, _reader);
        //获取材料
        QString materialName = spl["material"];
        if (materialName.isEmpty())
            return false;
        setSectionMaterial(materialName);
        //获取elset
        int modelID = this->getSetIDByName(spl["elset"], Interface::FITKModelEnum::FITKModelSetType::FMSElem);
        if (modelID == -1)return false;
        //读取材料方向
        if (spl.hasKey("orientation"))
            if (!this->materialOrientationR(line, modelID))
                return false;
        //设置名称
        QString name = QString("%1-").arg(section->getDataObjectName()) + spl["elset"];
        section->setDataObjectName(name);
        assign->assign(modelID, section->getDataObjectID());

        line = _reader->readLine();
        //获取应力

        return true;
    }

    bool FITKAbaqusAdaptorSection::materialOrientationR(QString line, int setId)
    {
        if (!_modelData || !_reader)return false;
        Interface::FITKAbaMaterialOrientationManager* materialOrientationManager = nullptr;
        Interface::FITKCoordinateSystemManager* csysManager = nullptr;
        if (_modelData->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AMTMIX)
        {
            //part
            AbaqusData::FITKAbaqusPart* partData = dynamic_cast<AbaqusData::FITKAbaqusPart*>(_modelData);
            if (!partData)return false;
            materialOrientationManager = partData->getMaterialOrientationManager();
            csysManager = partData->getCoordinateSystemManager();
        }
        if (!materialOrientationManager || !csysManager || !_reader)return false;
        //处理数据
        bool ok = true;
        InpKeyLineSpliter spl(line, _reader);
        //获取坐标系
        if (!spl.hasKey("orientation"))return false;
        QString name = QString("Ori_%1").arg(spl["orientation"]);
        //堆叠方向
        int stack = 3;
        if (spl.hasKey("stack direction"))
            stack = spl["stack direction"].toInt(&ok);
        if (!ok)return false;
        //获取Orientation关键字的第二行数据
        auto mapper = _reader->getReadInpInformationMapper();
        int sysId = 0;
        QString lineData = mapper->getOrientationSecondLine(name, _modelData->getDataObjectID(), sysId);
        if (sysId == 0)return false;
        //获取局部方向和旋转角
        QStringList str = lineData.split(',');
        if (str.size() != 2)return false;
        //局部方向
        int local = str.at(0).toDouble(&ok);
        if (!ok)return false;
        //旋转角
        double angle = str.at(1).toDouble(&ok);
        if (!ok)return false;
        //如果存在就不许创建
        //if (materialOrientationManager->getDataByName(name))
        //    return true;
        //需要判断是否存在，存在就需要重新设置name
        QString nameNew = materialOrientationManager->checkName(name);
        //创建材料方向
        Interface::FITKAbaMaterialOrientation* orientation = new Interface::FITKAbaMaterialOrientation;
        //设置所需数据
        orientation->setDataObjectName(nameNew);
        orientation->setCsysID(sysId);
        if (sysId != -1)
            orientation->setMaterialOrientationDefTpye(Interface::FITKAbaMaterialOrientation::MaterialOrientationDef::MOCoorSys);
        orientation->setRotateAxis(local);
        orientation->setRotateAngle(angle);
        orientation->setStackingDir(stack);
        orientation->setModelSetID(setId);
        //添加到管理器
        materialOrientationManager->appendDataObj(orientation);
        return true;
    }

    bool FITKAbaqusAdaptorSection::setSectionMaterial(QString materialName)
    {
        //获取数据存储器
        Interface::FITKAbaAbastractSection* section = dynamic_cast<Interface::FITKAbaAbastractSection*>(_dataObj);
        if (!section || !_reader || !_assign)
            return false;
        auto sm = _reader->getReadInpInformationMapper();
        sm->insertSectionDataMaterialName(section, materialName);       
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionW()
    {
        //获取数据存储器
        Interface::FITKAbaSectionBeam* section = dynamic_cast<Interface::FITKAbaSectionBeam*>(_dataObj);
        Interface::FITKAbaSectionAssignBeam* assign = dynamic_cast<Interface::FITKAbaSectionAssignBeam*>(_assign);
        if (!section || !_writer || !assign || !_modelData)
            return false;
        Interface::FITKAbaBeamOrientationManager* beamOrientationManager = nullptr;
        if (_modelData->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AMTMIX)
        {
            //part
            AbaqusData::FITKAbaqusPart* partData = dynamic_cast<AbaqusData::FITKAbaqusPart*>(_modelData);
            if (!partData)return false;
            beamOrientationManager = partData->getBeamOrientationManager();
        }
        if (!beamOrientationManager)return false;
        Interface::FITKModelSet* set = assign->getTModelObj<Interface::FITKModelSet>();
        if (!set) return false;
        //获取数据
        QString elsetName = set->getDataObjectName();
        elsetName = elsetName.contains(' ') ? QString("\"%1\"").arg(elsetName) : elsetName;
        QString materialName = section->getMaterialName();
        materialName = materialName.contains(' ') ? QString("\"%1\"").arg(materialName) : materialName;
        QTextStream* stream = _writer->getStream();
        QString temperature;
        if (section->getTemperatureVariation() == Interface::FITKAbaAbastractSection::TemperatureVariation::LinearByGradients)
            temperature = "GRADIENTS";
        else if (section->getTemperatureVariation() == Interface::FITKAbaAbastractSection::TemperatureVariation::InterpolatedFromTemperaturePoints)
            temperature = "VALUES";
        _profile = section->getProfile();
        if (!_profile)return false;
        //获取类型写出*Beam Section
        Interface::FITKAbaProfile::FITKAbaProfileShape type = _profile->getShape();
        if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::I)
        {
            *stream << "*Beam Section, elset=" << elsetName << ", material=" << materialName << ", temperature=" << temperature << ", section=I" << endl;
            if (!this->beamSectionProfileIW()) return false;
        }
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::L)
        {
            *stream << "*Beam Section, elset=" << elsetName << ", material=" << materialName << ", temperature=" << temperature << ", section=L" << endl;
            if (!this->beamSectionProfileLW()) return false;
        }
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::Box)
        {
            *stream << "*Beam Section, elset=" << elsetName << ", material=" << materialName << ", temperature=" << temperature << ", section=BOX" << endl;
            if (!this->beamSectionProfileBoxW()) return false;
        }
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::Pipe)
        {
            Interface::FITKAbaProfilePipe* profile = dynamic_cast<Interface::FITKAbaProfilePipe*>(_profile);
            if (!profile)return false;
            if (profile->getFormulation() == Interface::FITKAbaProfilePipe::PipeFormulation::ThickWalled)
                *stream << "*Beam Section, elset=" << elsetName << ", material=" << materialName << ", temperature=" << temperature << ", section=THICK PIPE" << endl;
            else if (profile->getFormulation() == Interface::FITKAbaProfilePipe::PipeFormulation::ThinWalled)
                *stream << "*Beam Section, elset=" << elsetName << ", material=" << materialName << ", temperature=" << temperature << ", section=PIPE" << endl;
            if (!this->beamSectionProfilePipeW()) return false;
        }
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::Circular)
        {
            *stream << "*Beam Section, elset=" << elsetName << ", material=" << materialName << ", temperature=" << temperature << ", section=CIRC" << endl;
            if (!this->beamSectionProfileCircularW()) return false;
        }
        else if (type == Interface::FITKAbaProfile::FITKAbaProfileShape::Rectangular)
        {
            *stream << "*Beam Section, elset=" << elsetName << ", material=" << materialName << ", temperature=" << temperature << ", section=RECT" << endl;
            if (!this->beamSectionProfileRectangularW()) return false;
        }
        int count = beamOrientationManager->getDataCount();
        Interface::FITKAbaBeamOrientation* beamDire = nullptr;
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaBeamOrientation* beamDireData = beamOrientationManager->getDataByIndex(i);
            if (!beamDireData)continue;
            if (beamDireData->getModelSetID() == set->getDataObjectID())
            {
                beamDire = beamDireData;
                break;
            }
        }
        if (!beamDire)return false;
        std::array<double, 3> direValue = beamDire->getN1Direction();
        *stream << QString("%1,%2,%3").arg(_writer->double2String(direValue[0], 8, 0)).arg(_writer->double2String(direValue[1], 8, 0)).arg(_writer->double2String(direValue[2], 8, 0)) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileIW()
    {
        Interface::FITKAbaProfileI* profile = dynamic_cast<Interface::FITKAbaProfileI*>(_profile);
        if (!profile)return false;
        QString l = _writer->double2String(profile->getI(), 9, 0);
        QString h = _writer->double2String(profile->geth(), 9, 0);
        QString b1 = _writer->double2String(profile->getb1(), 9, 0);
        QString b2 = _writer->double2String(profile->getb2(), 9, 0);
        QString t1 = _writer->double2String(profile->gett1(), 9, 0);
        QString t2 = _writer->double2String(profile->gett2(), 9, 0);
        QString t3 = _writer->double2String(profile->gett3(), 9, 0);
        QTextStream* stream = _writer->getStream();
        *stream << QString("%1, %2, %3, %4, %5, %6, %7").arg(l).arg(h).arg(b1).arg(b2).arg(t1).arg(t2).arg(t3) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileLW()
    {
        Interface::FITKAbaProfileL* profile = dynamic_cast<Interface::FITKAbaProfileL*>(_profile);
        if (!profile)return false;
        QString a = _writer->double2String(profile->getA(), 9, 0);
        QString b = _writer->double2String(profile->getB(), 9, 0);
        QString t1 = _writer->double2String(profile->getT1(), 9, 0);
        QString t2 = _writer->double2String(profile->getT2(), 9, 0);
        QTextStream* stream = _writer->getStream();
        *stream << QString("%1, %2, %3, %4").arg(a).arg(b).arg(t1).arg(t2) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileBoxW()
    {
        Interface::FITKAbaProfileBox* profile = dynamic_cast<Interface::FITKAbaProfileBox*>(_profile);
        if (!profile)return false;
        QTextStream* stream = _writer->getStream();
        QString w = _writer->double2String(profile->getWidth(), 9, 0);
        QString h = _writer->double2String(profile->getHeight(), 9, 0);
        if (Interface::FITKAbaProfileBox::BoxThickness::Individual == profile->getThicknessType())
        {
            QString t1 = _writer->double2String(profile->getT1(), 9, 0);
            QString t2 = _writer->double2String(profile->getT2(), 9, 0);
            QString t3 = _writer->double2String(profile->getT3(), 9, 0);
            QString t4 = _writer->double2String(profile->getT4(), 9, 0);
            *stream << QString("%1, %2, %3, %4, %5, %6").arg(w).arg(h).arg(t1).arg(t2).arg(t3).arg(t4) << endl;
        }
        else if (Interface::FITKAbaProfileBox::BoxThickness::Uniform == profile->getThicknessType())
        {
            QString thickness = _writer->double2String(profile->getThickness(), 9, 0);
            *stream << QString("%1, %2, %3, %4, %5, %6").arg(w).arg(h).arg(thickness).arg(thickness).arg(thickness).arg(thickness) << endl;
        }
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfilePipeW()
    {
        Interface::FITKAbaProfilePipe* profile = dynamic_cast<Interface::FITKAbaProfilePipe*>(_profile);
        if (!profile)return false;
        QString radius = _writer->double2String(profile->getRadius(), 9, 0);
        QString thickness = _writer->double2String(profile->getThickness(), 9, 0);
        QTextStream* stream = _writer->getStream();
        *stream << QString("%1, %2").arg(radius).arg(thickness) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileCircularW()
    {
        // 获取剖面的存储器
        Interface::FITKAbaProfileCircular* profile = dynamic_cast<Interface::FITKAbaProfileCircular*>(_profile);
        if (!profile)return false;
        QString r = _writer->double2String(profile->getR(), 9, 0);
        QTextStream* stream = _writer->getStream();
        *stream << QString("%1").arg(r) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorSection::beamSectionProfileRectangularW()
    {
        //获取剖面的存储器
        Interface::FITKAbaProfileRectangular* profile = dynamic_cast<Interface::FITKAbaProfileRectangular*>(_profile);
        if (!profile)return false;
        QString a = _writer->double2String(profile->getA(), 9, 0);
        QString b = _writer->double2String(profile->getB(), 9, 0);
        QTextStream* stream = _writer->getStream();
        *stream << QString("%1, %2").arg(a).arg(b) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorSection::shellHomogeneousSectionW()
    {
        //获取数据存储器
        Interface::FITKAbaSectionShellHomogeneous* section = dynamic_cast<Interface::FITKAbaSectionShellHomogeneous*>(_dataObj);
        Interface::FITKAbaSectionAssignShellHomogeneous* assign = dynamic_cast<Interface::FITKAbaSectionAssignShellHomogeneous*>(_assign);
        if (section == nullptr || assign == nullptr || !_writer)
            return false;
        Interface::FITKModelSet* set = assign->getTModelObj<Interface::FITKModelSet>();
        if (!set) return false;
        //获取数据
        QString elsetName = set->getDataObjectName();
        elsetName = elsetName.contains(' ') ? QString("\"%1\"").arg(elsetName) : elsetName;
        QString materialName = section->getMaterialName();
        materialName = materialName.contains(' ') ? QString("\"%1\"").arg(materialName) : materialName;
        QTextStream* stream = _writer->getStream();
        QString writeLine = QString("*Shell Section, elset=%1").arg(elsetName);
        //写出材料
        writeLine += QString(", material=%1").arg(materialName);
        //写出材料方向
        QString orientation = this->materialOrientationW(assign->getModelID(), false);
        if (!orientation.isEmpty())
            writeLine += orientation;
        Interface::FITKShellAssignEnum::ShellOffset type = assign->getShellOffset();
        //如果偏移为0就是中缅
        if (type == Interface::FITKShellAssignEnum::ShellOffset::SpecifyValue && fabs(assign->getShellOffsetValue()) < 1e-16)
            type = Interface::FITKShellAssignEnum::ShellOffset::MiddleSurface;
        QString value = _writer->double2String(assign->getShellOffsetValue(), 9, 0);
        //通过类型写出不同格式
        if (type == Interface::FITKShellAssignEnum::ShellOffset::MiddleSurface) {}
        else if (type == Interface::FITKShellAssignEnum::ShellOffset::TopSurface)
            writeLine += QString(", offset=SPOS");
        else if (type == Interface::FITKShellAssignEnum::ShellOffset::BottomSurface)
            writeLine += QString(", offset=SNEG");
        else if (type == Interface::FITKShellAssignEnum::ShellOffset::SFFromGeometry)
            writeLine += QString(", offset=");
        else if (type == Interface::FITKShellAssignEnum::ShellOffset::SpecifyValue)
            writeLine += QString(", offset=%1").arg(value);
        *stream << writeLine << endl;
        double thickness = section->getThickness();
        int points = section->getThicknessIntergrationPoints();
        *stream << _writer->double2String(thickness, 9, 0) << ", " << points << endl;
        return true;
    }

    bool FITKAbaqusAdaptorSection::solidHomogeneousSectionW()
    {
        //获取数据存储器
        Interface::FITKAbaSectionSolidHomogeneous* section = dynamic_cast<Interface::FITKAbaSectionSolidHomogeneous*>(_dataObj);
        Interface::FITKAbaSectionAssignSolidHomogenous* assign = dynamic_cast<Interface::FITKAbaSectionAssignSolidHomogenous*>(_assign);
        if (section == nullptr || assign == nullptr || !_writer)
            return false;
        Interface::FITKModelSet* set = assign->getTModelObj<Interface::FITKModelSet>();
        if (!set) return false;
        //获取数据
        QString elsetName = set->getDataObjectName();
        elsetName = elsetName.contains(' ') ? QString("\"%1\"").arg(elsetName) : elsetName;
        QString materialName = section->getMaterialName();
        materialName = materialName.contains(' ') ? QString("\"%1\"").arg(materialName) : materialName;
        QTextStream* stream = _writer->getStream();
        QString writeLine = QString("*Solid Section, elset=%1").arg(elsetName);
        //写出材料方向
        QString orientation = this->materialOrientationW(assign->getModelID(), true);
        if (!orientation.isEmpty())
            writeLine += orientation;
        //写出材料
        writeLine += QString(", material=%1").arg(materialName);
        *stream << writeLine << endl;
        *stream << "," << endl;
        return true;
    }

    int FITKAbaqusAdaptorSection::getSetIDByName(QString setName, int type)
    {
        Interface::FITKComponentManager* setManager = nullptr;
        if (_modelData->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AMTMIX)
        {
            //part
            AbaqusData::FITKAbaqusPart* partData = dynamic_cast<AbaqusData::FITKAbaqusPart*>(_modelData);
            if (!partData)return -1;
            setManager = partData->getComponentManager();
        }
        //获取模型数据
        if (!setManager)return -1;
        QList<Interface::FITKModelSet*> setList = setManager->getModelSet((Interface::FITKModelEnum::FITKModelSetType)type);

        for (auto set : setList)
        {
            if (set->getDataObjectName() == setName)
            {
                return set->getDataObjectID();
            }
        }
        _reader->consoleMessage(3, QString("Section Get Set Name Error, Name=%1. File:%2 Line:%3").arg(setName).arg(__FILE__).arg(__LINE__));
        return -1;
    }

    QString FITKAbaqusAdaptorSection::materialOrientationW(int setId, bool isStack)
    {
        if (!_modelData) return QString();
        Interface::FITKAbaMaterialOrientationManager* materialOrientationManager = nullptr;
        if (_modelData->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AMTMIX)
        {
            //part
            AbaqusData::FITKAbaqusPart* partData = dynamic_cast<AbaqusData::FITKAbaqusPart*>(_modelData);
            if (!partData)return QString();
            materialOrientationManager = partData->getMaterialOrientationManager();
        }
        QString data;
        if (!materialOrientationManager)return data;
        int count = materialOrientationManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            auto orientation = materialOrientationManager->getDataByIndex(i);
            if (!orientation)continue;
            //获取名称
            QString oriName = orientation->getDataObjectName();
            oriName = oriName.contains(' ') ? QString("\"%1\"").arg(oriName) : oriName;
            //判断是否具有材料方向
            Interface::FITKModelSet* materialOriSet = FITKDATAREPO->getTDataByID<Interface::FITKModelSet>(orientation->getModelSetID());
            Interface::FITKModelSet* sectionAssSet = FITKDATAREPO->getTDataByID<Interface::FITKModelSet>(setId);
            if (!sectionAssSet || !materialOriSet)continue;
            if (!(materialOriSet == sectionAssSet || materialOriSet->isContains(sectionAssSet)))continue;
            //获取写出的数据
            data += QString(", orientation=%1").arg(oriName);
            if (isStack && orientation->getStackingDir() != 3)
                data += QString(", stack direction=%1").arg(orientation->getStackingDir());
        }
        return data;
    }

}
